<template>
  <el-card>
    <el-form :model="state.searchForm">
      <el-row :gutter="20">
        <el-col :span="6">
          <el-form-item label="角色名称">
            <el-input
              v-model="state.searchForm.role_name"
              placeholder="角色名称"
              type="text"
            />
          </el-form-item>
        </el-col>
        <el-col :span="6">
          <el-form-item label="角色标识">
            <el-input
              v-model="state.searchForm.role_key"
              placeholder="角色标识"
              type="text"
            />
          </el-form-item>
        </el-col>
        <el-col :span="6">
          <el-button
            type="primary"
            @click="handlerSearch"
          >
            查询
          </el-button>
          <el-button
            type="info"
            @click="handlerReset"
          >
            重置
          </el-button>
        </el-col>
      </el-row>
    </el-form>
    <el-space
      wrap
      alignment="start"
      direction="vertical"
      :size="20"
    >
      <el-button
        type="primary"
        @click="showForm(1)"
      >
        新增角色
      </el-button>
      <div />
    </el-space>
    <el-table
      :data="state.dataList"
      border
      style="width: 100%"
    >
      <el-table-column
        prop="role_id"
        label="角色ID"
        width="120"
        align="center"
      />
      <el-table-column
        prop="role_name"
        label="用户名"
        width="120"
        align="center"
      />
      <el-table-column
        prop="role_key"
        label="角色标识"
        width="120"
        align="center"
      />
      <el-table-column
        prop="role_sort"
        label="排序"
        width="120"
        align="center"
      />
      <el-table-column
        prop="status"
        label="角色状态"
        width="120"
        align="center"
      >
        <template #default="scope">
          <el-tag
            class="ml-2"
            v-if="scope.row.status == 0"
          >
            正常
          </el-tag>
          <el-tag
            class="ml-2"
            v-else
            type="danger"
          >
            禁用
          </el-tag>
        </template>
      </el-table-column>
      <el-table-column
        prop="remark"
        label="备注"
        width="120"
        align="center"
      />
      <el-table-column
        prop="create_time"
        label="创建时间"
        width="160"
        align="center"
      >
        <template #default="scope">
          <span>{{ dateFormat(scope.row.create_time) }}</span>
        </template>
      </el-table-column>
      <el-table-column
        prop="update_time"
        label="更新时间"
        width="160"
        align="center"
      >
        <template #default="scope">
          <span>{{ dateFormat(scope.row.update_time) }}</span>
        </template>
      </el-table-column>
      <el-table-column
        label="操作"
        align="center"
        fixed="right"
        width="160"
      >
        <template #default="scope">
          <el-button
            text
            type="primary"
            @click="showForm(2, scope.row)"
          >
            编辑
          </el-button>
          <el-button
            type="danger"
            text
            @click="handlerDel(scope.row.role_id)"
          >
            删除
          </el-button>
        </template>
      </el-table-column>
    </el-table>
    <tf-pagination
      :page="state.page"
      :total="state.total"
      @on-change="(e) => paginationChange(e)"
    />

    <el-dialog
      v-model="state.showVisible"
      append-to-body
      title="新增/编辑 角色信息"
      width="700px"
      destroy-on-close
    >
      <el-form
        status-icon
        ref="formRef"
        :model="form"
        :rules="formRules"
        label-width="100"
      >
        <el-row :gutter="20">
          <el-col :span="12">
            <el-form-item
              prop="role_name"
              label="角色名称"
            >
              <el-input
                v-model="form.role_name"
                placeholder="角色名称"
                type="text"
              />
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item
              prop="role_key"
              label="角色标识"
            >
              <el-input
                v-model="form.role_key"
                placeholder="角色标识"
                type="text"
              />
            </el-form-item>
          </el-col>
          <el-col :span="24">
            <el-form-item
              prop="menu_ids"
              label="菜单权限"
            >
              <el-checkbox v-model="stateCheckBox.IsCheckAll" label="全选/全不选" @change="handlerCheckAll" />
              <el-checkbox v-model="stateCheckBox.IsLinked" label="父子联动" />
              <el-scrollbar :max-height="300">
                <el-tree
                  class="menu_tree"
                  ref="menuTree"
                  :data="state.treeMenuList"
                  :default-checked-keys="form.menu_ids"
                  show-checkbox
                  check-on-click-node
                  default-expand-all
                  node-key="menu_id"
                  @check="handlerTreeCheck"
                  :check-strictly="!stateCheckBox.IsLinked"
                  :props="{
                    children: 'children', label: 'menu_name',
                  }"
                />
              </el-scrollbar>
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item
              prop="status"
              label="状态"
            >
              <el-radio-group v-model="form.status">
                <el-radio :label="0">
                  启用
                </el-radio>
                <el-radio :label="1">
                  禁用
                </el-radio>
              </el-radio-group>
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item
              prop="role_sort"
              label="显示顺序"
            >
              <el-input-number
                v-model="form.role_sort"
                :min="1"
                :max="999"
              />
            </el-form-item>
          </el-col>
          <el-col :span="24">
            <el-form-item
              label="角色备注"
            >
              <el-input
                v-model="form.remark"
                placeholder="角色备注"
                resize="none"
                :autosize="{ minRows: 3, maxRows: 4 }"
                :maxlength="120"
                show-word-limit
                type="textarea"
              />
            </el-form-item>
          </el-col>
        </el-row>
      </el-form>
      <template #footer>
        <span class="dialog-footer">
          <el-button @click="state.showVisible = false">取消</el-button>
          <el-button
            type="primary"
            @click="saveForm(formRef)"
          >
            {{ state.actionType == 1 ? '添加' : '更新' }}
          </el-button>
        </span>
      </template>
    </el-dialog>
  </el-card>
</template>
<script setup lang="ts">
import { ref, reactive, onMounted, nextTick } from 'vue'
import { ElMessage, type FormInstance } from 'element-plus'
import { updateUser } from '@/api/user'
import { getRoleList, delRole, addRole, getRoleMenu, updateRole } from '@/api/role'
import { dateFormat } from '@/utils/filters'
import { getMenutreeList } from '@/api/menu'
import { IsStrNotSymbol, IsnotNull, minMaxLength } from '@/utils/validate'
const DEFAULT_SEARCH_FORM = {
  role_name: '',
  role_key: ''
}
const state = reactive({
  dataList: [], // 角色列表
  total: 0, // 总条数
  showVisible: false, // 是否显示编辑弹框
  actionType: 1, // 超炒操作类型 1 添加 2 修改
  treeMenuList: [], // 菜单树形下拉列表
  page: { // 分页数据
    pageIndex: 1,
    pageSize: 10
  },
  searchForm: { ...DEFAULT_SEARCH_FORM } // 帅选条件
})
const stateCheckBox = reactive({
  IsCheckAll: false, // 石佛全选
  IsLinked: true // 是否联动
})
const formRef = ref()
const menuTree = ref()
const form = reactive<any>({
  role_id: '', // 角色id
  menu_ids: [], // 菜单id
  status: 0, // 状态
  role_sort: 1,
  role_name: null, // 角色名称
  role_key: '', // 角色标识
  remark: '' // 备注
})
const formRules = reactive({
  role_name: IsnotNull('请输入角色名称').concat(minMaxLength(2, 10)),
  role_key: IsnotNull('请输入角色标识').concat(IsStrNotSymbol()),
  menu_ids: IsnotNull('请选择菜单权限'),
  status: IsnotNull('请选择角色状态'),
  role_sort: IsnotNull('请输入角色排序顺序')
})
// 分页页码改变事件
function paginationChange (event: any): void {
  state.page.pageIndex = event.pageIndex
  getList()
}
// 条件搜索
function handlerSearch (): void {
  getList()
}
// 重置
function handlerReset (): void {
  state.searchForm = { ...DEFAULT_SEARCH_FORM }
  getList()
}
// 获取用户列表
function getList (): void {
  const data = { ...state.page, ...state.searchForm }
  getRoleList(data).then((res: any) => {
    state.dataList = res.list
    state.total = res.total
  })
}
// 获取树形菜单下拉列表
function getTreeList (): void {
  getMenutreeList().then((res: any) => {
    state.treeMenuList = res[0].children
  })
}
// 更新菜单选择
function setChecked (): void {
  const nodes = menuTree.value.getCheckedNodes()
  form.menu_ids = nodes.map((node: any) => node.menu_id)
}
// 全选全不选
function handlerCheckAll (): void {
  void nextTick(() => {
    if (stateCheckBox.IsCheckAll) {
      menuTree.value.setCheckedNodes(state.treeMenuList)
    } else {
      menuTree.value.setCheckedNodes([])
    }
    setChecked()
  })
}
// 点击节点及多选框时触发
function handlerTreeCheck (_e: any): void {
  setChecked()
}
// 显示编辑用户框
async function showForm (type: number, data?: any): Promise<void> {
  getTreeList()
  state.actionType = type
  try {
    if (type === 2) {
      Object.keys(data).forEach((key: string) => {
        form[key] = data[key]
      })
      const result = await getRoleMenu(data.role_id)
      form.menu_ids = result.map((item: any) => item.menu_id)
    }
    state.showVisible = true
    void nextTick(() => {
      formRef.value.resetFields()
    })
  } catch (error: any) {
    console.log('error', error)
    ElMessage.error(error)
  }
}
// 保存用户
async function saveForm (el: FormInstance): Promise<any> {
  await el.validate((val: boolean) => {
    if (val) {
      if (state.actionType === 1) {
        addRole(form).then(() => {
          state.showVisible = false
          getList()
        })
      } else {
        const obj = { ...form }
        delete obj.role_id
        delete obj.update_time
        delete obj.create_time
        updateRole(form.role_id, obj).then(() => {
          getList()
          state.showVisible = false
        })
      }
    } else {
      return false
    }
  })
}
// 删除
async function handlerDel (role_id: string): Promise<void> {
  try {
    await delRole(role_id)
  } catch (error: any) {
    ElMessage.error(error?.message)
  }
}
onMounted(async () => {
  getList()
})
</script>
<style scoped lang="scss">
.menu_tree {
  width: 560px;
  border: 1px solid #eeeeee;
}
</style>
